import java.awt.Color;
import java.awt.Graphics;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.events.ServerMessageEvent;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.event.listeners.ServerMessageListener;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSInterfaceChild;
import com.speljohan.rsbot.script.wrappers.RSItem;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class TCannonBalls extends Script implements ServerMessageListener,
		PaintListener {

	RSInterfaceChild make = RSInterface.getChildInterface(309, 6);
	RSItem bar = new RSItem(2353, 1);

	RSObject bankBooth = null;
	RSObject furnace = null;

	RSTile[] Bank2Furnace = new RSTile[] { new RSTile(2946, 3369),
			new RSTile(2950, 3375), new RSTile(2955, 3379),
			new RSTile(2961, 3380), new RSTile(2967, 3380),
			new RSTile(2974, 3370) };

	RSTile[] Furnace2Bank = reversePath(Bank2Furnace);

	int lastMessage = (int) System.currentTimeMillis();
	int startExp = 0;
	int startTime = 0;
	int startBalls = 0;

	double version = 1.0;

	boolean gotExp;

	public TCannonBalls() {
		setParameter("author", "!@!@!");
		setParameter("version", version);
		setParameter("name", "TCannonBalls");
		setParameter("category", "Smithing");
		setParameter("description", desc());
	}

	public void antiBan() {
		final int x = random(0, 15);

		switch (x) {
		case 1:
			turnCamera();
			break;
		case 2:
			if (random(0, 3) == 1) {
				tab(true);
			} else {
				tab(false);
			}
			break;
		}
	}

	public int checkState() {
		if (distanceTo(Furnace2Bank[0]) < 5 && getInventoryCount(2353) > 0) {
			return 2;
		}
		if (distanceTo(Bank2Furnace[0]) < 5 && getInventoryCount(2353) < 1) {
			return 1;
		}
		return 0;
	}

	public String desc() {
		String s = "";
		s += "<html><body><center>";
		s += "<br><br><br><br>";
		s += "<font size=8><b>TCannonBalls</b></font><br>Version: " + version;
		s += "<br><br>Just start in fally! :D";
		s += "</center></body></html>";
		return s;
	}

	@SuppressWarnings("deprecation")
	@Override
	public int loop() {
		final RSObject furnace = getNearestObjectByID(11666);
		final RSObject bankBooth = getNearestObjectByID(11758);

		if (getMyPlayer().isMoving()
				&& distanceTo(getDestination()) > random(2, 5)) {
			return random(100, 300);
		}

		if (getEnergy() > random(30, 90)) {
			setRun(true);
		}

		if (getInventoryCount(4) == 0 || !onPath()) {
			log("no mould... D:");
			stopAllScripts();
		}

		if (getMyPlayer().isInCombat()) {
			runAway();
			return random(1000, 2000);
		}

		if (getMyPlayer().getAnimation() != -1
				|| (int) System.currentTimeMillis() - lastMessage < 2000) {
			antiBan();
			return random(800, 2000);
		}

		if (RSInterface.getChildInterface(309, 6).isValid()) {
			atInterface(RSInterface.getChildInterface(309, 6), "Make all");
			return random(1000, 1200);
		}

		switch (checkState()) {

		case 0: // walking
			if (onPath() && distanceTo(Bank2Furnace[0]) > 3
					&& getInventoryCount(2353) == 0) {
				walkPathMM(randomizePath(Furnace2Bank, 2, 2), 16);
			}
			if (onPath() && distanceTo(Furnace2Bank[0]) > 3
					&& getInventoryCount(2353) > 0) {
				walkPathMM(randomizePath(Bank2Furnace, 2, 2), 16);
			}
			return random(300, 700);

		case 1: // withdraw bars
			if (!tileOnScreen(bankBooth.getLocation())) {
				walkTileMM(bankBooth.getLocation());
				waitUntilStop();
			}
			if (tileOnScreen(bankBooth.getLocation())) {
				if (RSInterface.getInterface(Constants.INTERFACE_BANK).isNull()) {
					atObject(bankBooth, "Use-q");
				}
				if (RSInterface.getInterface(Constants.INTERFACE_BANK)
						.isValid()) {
					depositAllExcept(2, 4);
					withdrawBars();
				}
			}
			return random(300, 700);

		case 2: // smelting
			if (!tileOnScreen(furnace.getLocation())) {
				walkTileMM(furnace.getLocation());
				waitUntilStop();
			}
			if (tileOnScreen(furnace.getLocation())) {
				useItemOnObject(2353, 11666, "Use Steel Bar -> Furnace");
			}
			return random(200, 500);

		}
		return random(400, 700);
	}

	@Override
	public void onFinish() {
		Bot.getEventManager().removeListener(this);
		log("Thanks for using TCannonBalls. :)");
	}

	public boolean onPath() {
		for (final RSTile t : Bank2Furnace) {
			if (distanceTo(t) < 16) {
				return true;
			}
		}
		return false;
	}

	public void onRepaint(final Graphics x) {
		x.setColor(Color.BLACK);
		x.fill3DRect(315, 350, 160, 80, true);

		x.setColor(Color.RED);
		x.drawString("TCannonBalls v" + version, 325, 370);
		x.drawString("Time Running: " + runTime(), 325, 385);
		final int EXP = skills.getCurrentSkillExp(Constants.STAT_SMITHING);
		if (gotExp) {
			x.drawString("Exp gained: " + (EXP - startExp), 325, 400);
		}
		x.drawString("Balls made: " + (getInventoryCount(2) - startBalls), 325,
				415);
	}

	@Override
	public boolean onStart(final String args[]) {
		startTime = (int) System.currentTimeMillis();
		gotExp = false;
		return true;
	}

	public void runAway() {
		RSTile foo, bar, bar2;
		foo = getMyPlayer().getLocation();
		setRun(true);

		bar = new RSTile(foo.getX() + random(8, 10), foo.getY() + random(8, 10));
		bar2 = new RSTile(foo.getX() + random(-8, -10), foo.getY()
				+ random(-8, -10));
		if (bar.isValid()) {
			walkTileMM(bar);
		} else if (bar2.isValid()) {
			walkTileMM(bar2);
		}
		waitUntilStop();
		wait(random(1000, 2000));
		walkTileMM(foo);
	}

	public String runTime() {
		final int time = (int) System.currentTimeMillis() - startTime;
		int seconds = time / 1000, minutes = 0, hours = 0;
		String timeString = "";
		if (seconds >= 60) {
			minutes = seconds / 60;
			seconds -= minutes * 60;
		}
		if (minutes >= 60) {
			hours = minutes / 60;
			minutes -= hours * 60;
		}
		if (hours < 10) {
			timeString += "0" + hours + ":";
		} else {
			timeString += hours + ":";
		}
		if (minutes < 10) {
			timeString += "0" + minutes + ":";
		} else {
			timeString += minutes + ":";
		}
		if (seconds < 10) {
			timeString += "0" + seconds;
		} else {
			timeString += seconds;
		}
		return timeString;
	}

	public void serverMessageRecieved(final ServerMessageEvent e) {
		if (e.getMessage().contains("")) {
			if (!gotExp) {
				startExp = skills.getCurrentSkillExp(Constants.STAT_SMITHING);
				startBalls = getInventoryCount(2);
				gotExp = true;
			}
		}
		if (e.getMessage().contains("You remove the cannonballs")) {
			lastMessage = (int) System.currentTimeMillis();
		}
		if (e.getMessage().contains("You heat the")) {
			lastMessage = (int) System.currentTimeMillis();
		}
		if (e.getMessage().contains("You pour the")) {
			lastMessage = (int) System.currentTimeMillis();
		}
		if (e.getMessage().contains("The molten metal")) {
			lastMessage = (int) System.currentTimeMillis();
		}
	}

	public void tab(final boolean stupid) {
		final int[] nonStupidTabs = { Constants.TAB_CLAN,
				Constants.TAB_FRIENDS, Constants.TAB_INVENTORY,
				Constants.TAB_MUSIC, Constants.TAB_OPTIONS, Constants.TAB_STATS };
		if (stupid) {
			final int i = random(0, 14);
			if (getCurrentTab() != i) {
				openTab(i);
			}
		} else if (!stupid) {
			final int i = random(0, nonStupidTabs.length - 1);
			if (getCurrentTab() != i) {
				openTab(i);
			}
		}
	}

	public boolean turnCamera() {
		try {
			setCameraAltitude(true);
			int newCamera = getCameraAngle() + random(0, 270);
			if (newCamera >= 360) {
				newCamera -= 360;
			}
			setCameraRotation(newCamera);
		} catch (final Exception e) {
			return false;
		}
		return true;
	}

	public boolean useItemOnObject(final int ID, final int objID,
			final String action) {
		final RSItem item = new RSItem(ID, 1);
		final RSObject obj = getNearestObjectByID(objID);
		if (item == null || obj == null) {
			return false;
		}
		if (!tileOnScreen(obj.getLocation())) {
			return false;
		}
		atInventoryItem(2353, "Use");
		return atTile(obj.getLocation(), action);
	}

	public void waitUntilStop() {
		wait(random(500, 700));
		while (getMyPlayer().isMoving()
				&& distanceTo(getDestination()) > random(2, 5)) {
			wait(random(50, 150));
		}
	}

	public boolean withdrawBars() {
		moveMouse(53, 106);
		clickMouse(false);
		return atMenu("Withdraw-all");
	}

}